/* libue.h */

#ifndef UE_LIB_H
#define UE_LIB_H

#include "UEMessage.h"

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

#define LIB_UE_VERSION                            1      /* protocol version of libue */

#define UE_ERR_SUCCESS                            0      /* success */
#define UE_ERR_INVALID_PARAMETER                  1      /* incorrect parameter passed to functions */
#define UE_ERR_SOCKET                             2      /* socket error when send/recv data */
#define UE_ERR_INVALID_REQUEST                    3      /* the request is not a valid UE request */
#define UE_ERR_INVALID_RESPONSE                   4      /* the response is not a valid UE response */
#define UE_ERR_INVALID_AUTHENTICATION             5      /* authenticate failed */
#define UE_ERR_OUT_OF_MEMORY                      6      /* malloc memory failed */
#define UE_ERR_SERVER_ERROR                      99      /* UE server response failed status */

/* Block read all the data specified by len from socket.
 * @param[in] s Socket file descriptor used to send the data
 * @param[in] buf Pointer to the buffer of the data to store the read data.
 * @param[in] len Length of the data to be read.
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int readdata(const int s, char* buf, unsigned int len);

/* Send the whole data to socket.
 * @param[in] s Socket file descriptor used to send the data
 * @param[in] buf Pointer to the buffer of the data to be sent.
 * @param[in] len Length of the data to be sent.
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int senddata(const int s, const char* buf, unsigned int len);

/* Connect to UEServer and return the socket file descriptor of the connection.
 * @param[in] address Null-terminated string of the UEServer address.
 * @param[in] port Port of the UEServer to be connected.
 * @param[out] s Socket file descriptor for the established connection.
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int ue_connect(const char* address, const unsigned short port, int* s);

/* Authenticate a connection to UEServer.
 * @param[in] s Socket file descriptor for the connection to be authenticated.
 * @param[in] key String value of the authentication used to authenticate the connection.
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int ue_authenticate(int s, const char* key);

/* Send action to server and receive server response.
 * @param[in] s Socket file descriptor for the connection to be authenticated.
 * @param[in] action_data The action taken by client.
 * @param[out] pupdate_data Store the repond data. After use it, call ue_response_free to avoid memory leak 
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int ue_action(int s, ue_action_data* action_data, ue_update_data **pupdate_data);

/* Send update request to server and receive server response.
 * @param[in] s Socket file descriptor for the connection to be authenticated.
 * @param[in] ueid_client The last ueid of client.
 * @param[out] pupdate_data Store the repond heartbeat data. After use it, call ue_response_free to avoid memory leak 
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int ue_udpate(int s, int ueid_client, ue_update_data **pupdate_data);

/* Get the update data of specified ueid.
 * @param[in] s Socket file descriptor for the connection to be authenticated.
 * @param[in] ueid Indicate whitch udpate data to get
 * @param[out] pupdate_item Pointer to store the update time. After use it, call ue_response_free to avoid memory leak.
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
//int ue_udpate(int s, int ueid, ue_update_item **pupdate_item);

/* Send request to UEServer and get response
 * @param[in] s Socket file descriptor for send the request.
 * @param[in] request_header The request header.
 * @param[in] request_data The request data.
 * @param[out] response_header Store the response header.
 * @param[out] presponse_data Pointer to the buffer to store the response data.After finish use it, call ue_response_free to avoid memory leak.
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int ue_request(int s, ue_request_header *request_header, const char* request_data, ue_response_header *response_header, void** presponse_data);

/* Free the memory alloc to store the response data
 * @param[in] response_header The response header.
 * @param[in] response_data The response data.
 * @return UE_ERR_SUCCESS indicate success, otherwise some error occur.
 */
int ue_response_free(ue_response_header *response_header, void* response_data);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* UE_LIB_H */